#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>

struct Node{
	int data;
	struct Node* next;
};

pthread_cond_t cond;
pthread_mutex_t mutex;

struct Node*head=NULL;

void*product(void*arg)
{
	while(1)
	{
		pthread_mutex_lock(&mutex);
		struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
		if(newNode==NULL)
		{
			printf("fail");
			return NULL;
		}

		newNode->data=rand()%100;
		newNode->next=head;

		head=newNode;

		printf("producter, id: %ld, data:%d\n",pthread_self(),newNode->data);
		pthread_mutex_unlock(&mutex);
		pthread_cond_broadcast(&cond);
		sleep(1000);
	}
	return NULL;
}

void*consumer(void*arg)
{
	while(1)
	{
		pthread_mutex_lock(&mutex);

		//condition change line
		struct Node* node=head;

		while(head==NULL)
		{
			pthread_cond_wait(&cond,&mutex);
		}

		printf("consumer, id: %ld, data:%d\n",pthread_self(),node->data);
		head=head->next;
		free(node);
		pthread_mutex_unlock(&mutex);
		sleep(1000);
	}
	return NULL;
}

int main()
{

	//chu shi hua
	pthread_mutex_init(&mutex,NULL);
	pthread_cond_init(&cond,NULL);
	pthread_t t1[5],t2[5];
	for(int i=0;i<5;i++)
	{
		pthread_create(&t1[i],NULL,product,NULL);
	}
	for(int i=0;i<5;i++)
	{
		pthread_create(&t2[i],NULL,consumer,NULL);
	}

	for(int i=0;i<5;i++)
	{
		pthread_join(t1[i],NULL);
		pthread_join(t2[i],NULL);
	}

	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);

	return 0;
}
